#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
属性编辑器模块
提供CEGUI布局编辑器的属性编辑功能
"""

from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QTableWidget, 
                           QTableWidgetItem, QPushButton, QHeaderView, QMessageBox,
                           QPlainTextEdit, QDialog, QLabel, QDialogButtonBox)
from PyQt5.QtCore import Qt, pyqtSignal, QSize

class TextEditDialog(QDialog):
    """用于编辑多行文本的对话框"""
    
    def __init__(self, parent=None, text="", title="编辑属性值"):
        super(TextEditDialog, self).__init__(parent)
        self.setWindowTitle(title)
        self.resize(500, 300)
        
        # 创建布局
        layout = QVBoxLayout(self)
        
        # 添加文本编辑器
        self.text_edit = QPlainTextEdit(self)
        self.text_edit.setPlainText(text)
        layout.addWidget(self.text_edit)
        
        # 添加按钮
        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)
    
    def get_text(self):
        """获取编辑后的文本"""
        return self.text_edit.toPlainText()

class PropertyEditor(QWidget):
    """属性编辑器部件"""
    
    # 定义信号
    property_changed = pyqtSignal(object, str, str)
    
    def __init__(self, parent=None):
        super(PropertyEditor, self).__init__(parent)
        self.current_element = None
        self.coordinate_mode = 'relative'  # 添加坐标模式
        self.init_ui()
    
    def init_ui(self):
        """初始化UI"""
        # 创建布局
        layout = QVBoxLayout(self)
        layout.setContentsMargins(2, 2, 2, 2)
        
        # 创建属性表格
        self.property_table = QTableWidget(0, 2)
        self.property_table.setHorizontalHeaderLabels(['属性', '值'])
        
        # 设置水平表头不强制等分，允许用户调整
        self.property_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive)
        self.property_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Interactive)
        # 设置初始列宽比例，默认属性列稍窄
        self.property_table.horizontalHeader().resizeSection(0, 120)
        self.property_table.horizontalHeader().resizeSection(1, 200)
        # 表头可拖动
        self.property_table.horizontalHeader().setSectionsMovable(False)
        # 表头可见
        self.property_table.horizontalHeader().setVisible(True)
        # 设置拉伸最后一列
        self.property_table.horizontalHeader().setStretchLastSection(True)
        
        self.property_table.verticalHeader().setVisible(False)
        
        # 设置单元格自动换行
        self.property_table.setWordWrap(True)
        self.property_table.setTextElideMode(Qt.ElideNone)
        
        # 连接双击信号
        self.property_table.cellDoubleClicked.connect(self.on_cell_double_clicked)
        
        # 添加到布局
        layout.addWidget(self.property_table)
        
        # 添加按钮
        button_layout = QHBoxLayout()
        
        add_property_button = QPushButton('添加属性')
        add_property_button.clicked.connect(self.add_property)
        button_layout.addWidget(add_property_button)
        
        remove_property_button = QPushButton('删除属性')
        remove_property_button.clicked.connect(self.remove_property)
        button_layout.addWidget(remove_property_button)
        
        layout.addLayout(button_layout)
    
    def set_element(self, element):
        """设置当前元素并更新属性表格"""
        self.current_element = element
        self.update_property_table()
    
    def set_coordinate_mode(self, mode):
        """设置坐标模式
        
        参数:
            mode: 坐标模式，'relative' 或 'absolute'
        """
        if mode in ['relative', 'absolute']:
            self.coordinate_mode = mode
            
    def get_coordinate_mode(self):
        """获取当前坐标模式
        
        返回:
            str: 当前坐标模式
        """
        return self.coordinate_mode
        
    def format_coordinate_value(self, prop_name, prop_value):
        """根据坐标模式格式化坐标值显示
        
        参数:
            prop_name: 属性名
            prop_value: 属性值
            
        返回:
            str: 格式化后的显示值
        """
        if prop_name == 'UnifiedAreaRect' and self.coordinate_mode == 'absolute':
            # 在绝对像素模式下，显示像素坐标
            try:
                # 解析UnifiedAreaRect值
                import re
                pattern = r"\{\{([\d\.-]+),[\d\.-]+\},\{([\d\.-]+),[\d\.-]+\},\{([\d\.-]+),[\d\.-]+\},\{([\d\.-]+),[\d\.-]+\}\}"
                match = re.match(pattern, prop_value.replace(' ', ''))
                
                if match:
                    x1 = float(match.group(1))
                    y1 = float(match.group(2))
                    x2 = float(match.group(3))
                    y2 = float(match.group(4))
                    
                    # 获取主窗口以获取当前分辨率
                    main_window = self.get_main_window()
                    if main_window and hasattr(main_window, 'design_view'):
                        width, height = main_window.design_view.get_resolution()
                        
                        # 计算绝对像素坐标
                        abs_x1 = int(x1 * width)
                        abs_y1 = int(y1 * height)
                        abs_x2 = int(x2 * width)
                        abs_y2 = int(y2 * height)
                        
                        # 计算宽度和高度
                        abs_width = abs_x2 - abs_x1
                        abs_height = abs_y2 - abs_y1
                        
                        return f"位置: ({abs_x1}, {abs_y1})\n尺寸: {abs_width}×{abs_height}\n原始: {prop_value}"
                    
            except Exception as e:
                print(f"格式化坐标值时出错: {e}")
                
        return prop_value
        
    def get_main_window(self):
        """获取主窗口引用"""
        # 向上遍历父组件找到主窗口
        parent = self.parent()
        while parent:
            if hasattr(parent, 'design_view'):
                return parent
            parent = parent.parent()
        return None
    
    def update_property_table(self):
        """更新属性表格"""
        # 先断开之前的信号连接
        try:
            self.property_table.itemChanged.disconnect()
        except TypeError:
            # 如果之前没有连接，会抛出TypeError
            pass
            
        self.property_table.setRowCount(0)
        
        if not self.current_element:
            return
        
        # 添加元素属性
        row = 0
        for attr_name, attr_value in self.current_element.attrib.items():
            self.property_table.insertRow(row)
            
            # 属性名
            name_item = QTableWidgetItem(attr_name)
            name_item.setFlags(name_item.flags() & ~Qt.ItemIsEditable)  # 不可编辑
            self.property_table.setItem(row, 0, name_item)
            
            # 属性值 - 启用自动换行
            value_item = QTableWidgetItem(attr_value)
            value_item.setTextAlignment(Qt.AlignTop | Qt.AlignLeft)  # 顶部对齐
            value_item.setFlags(value_item.flags() & ~Qt.ItemIsEditable)  # 不直接编辑，使用双击
            self.property_table.setItem(row, 1, value_item)
            
            row += 1
        
        # 添加Property元素属性
        for prop in self.current_element.findall('Property'):
            name = prop.get('Name')
            value = prop.get('Value')
            
            self.property_table.insertRow(row)
            
            # 属性名
            name_item = QTableWidgetItem(name)
            name_item.setFlags(name_item.flags() & ~Qt.ItemIsEditable)  # 不可编辑
            self.property_table.setItem(row, 0, name_item)
            
            # 属性值 - 根据坐标模式格式化显示
            formatted_value = self.format_coordinate_value(name, value)
            value_item = QTableWidgetItem(formatted_value)
            value_item.setTextAlignment(Qt.AlignTop | Qt.AlignLeft)  # 顶部对齐
            value_item.setFlags(value_item.flags() & ~Qt.ItemIsEditable)  # 不直接编辑，使用双击
            self.property_table.setItem(row, 1, value_item)
            
            row += 1
        
        # 调整行高度以适应内容
        for i in range(self.property_table.rowCount()):
            self.adjust_row_height(i)
        
        # 强制更新表格
        self.property_table.update()
        
        # 连接编辑完成信号
        self.property_table.itemChanged.connect(self.on_property_item_changed)
    
    def adjust_row_height(self, row):
        """调整指定行的高度以适应内容"""
        value_item = self.property_table.item(row, 1)
        if value_item:
            text = value_item.text()
            lines = text.split('\n')
            
            # 计算更准确的行高，增加每行高度并添加额外空间
            font_metrics = self.property_table.fontMetrics()
            line_height = font_metrics.height() + 4  # 字体高度加上一点额外空间
            
            # 计算文本内容所需的实际高度
            content_height = len(lines) * line_height
            
            # 设置最小高度并添加边距
            height = max(content_height + 10, 30)  # 添加10像素的边距，最小高度30
            
            # 设置行高，适当增加以确保完全显示
            self.property_table.setRowHeight(row, height)
            
            # 强制更新表格
            self.property_table.update()
    
    def on_cell_double_clicked(self, row, column):
        """单元格双击事件处理"""
        # 只处理值列的双击
        if column == 1 and self.current_element:
            item = self.property_table.item(row, column)
            name_item = self.property_table.item(row, 0)
            
            if item and name_item:
                name = name_item.text()
                current_value = item.text()
                
                # 显示文本编辑对话框
                dialog = TextEditDialog(self, current_value, f"编辑属性: {name}")
                if dialog.exec_() == QDialog.Accepted:
                    new_value = dialog.get_text()
                    
                    # 如果值有变化
                    if new_value != current_value:
                        # 更新表格项
                        item.setText(new_value)
                        
                        # 检查是否为元素属性
                        if name in self.current_element.attrib:
                            self.current_element.set(name, new_value)
                        else:
                            # 发送属性变更信号
                            self.property_changed.emit(self.current_element, name, new_value)
                        
                        # 调整行高
                        self.adjust_row_height(row)
                        
                        # 强制更新表格
                        self.property_table.update()
    
    def on_property_item_changed(self, item):
        """属性项编辑完成"""
        if not self.current_element:
            return
        
        row = item.row()
        col = item.column()
        
        # 只处理值列的变更
        if col == 1:
            name = self.property_table.item(row, 0).text()
            value = item.text()
            
            # 检查是否为元素属性
            if name in self.current_element.attrib:
                self.current_element.set(name, value)
            else:
                # 发送属性变更信号
                self.property_changed.emit(self.current_element, name, value)
            
            # 调整行高
            self.adjust_row_height(row)
            
            # 强制更新表格
            self.property_table.update()
    
    def add_property(self):
        """添加新属性"""
        if not self.current_element:
            QMessageBox.warning(self, '警告', '请先选择一个元素')
            return
        
        # 添加新行
        row = self.property_table.rowCount()
        self.property_table.insertRow(row)
        
        # 设置属性名
        name_item = QTableWidgetItem('新属性')
        name_item.setFlags(name_item.flags() | Qt.ItemIsEditable)  # 新增的属性名允许编辑一次
        self.property_table.setItem(row, 0, name_item)
        
        # 设置属性值
        value_item = QTableWidgetItem('值')
        value_item.setFlags(value_item.flags() & ~Qt.ItemIsEditable)  # 不直接编辑，使用双击
        self.property_table.setItem(row, 1, value_item)
        
        # 选中新添加的属性名称
        self.property_table.setCurrentCell(row, 0)
        self.property_table.editItem(name_item)  # 直接进入编辑模式
    
    def remove_property(self):
        """删除选中的属性"""
        if not self.current_element:
            QMessageBox.warning(self, '警告', '请先选择一个元素')
            return
        
        current_row = self.property_table.currentRow()
        if current_row < 0:
            QMessageBox.warning(self, '警告', '请先选择一个属性')
            return
        
        name = self.property_table.item(current_row, 0).text()
        
        # 确认删除
        reply = QMessageBox.question(self, '确认', f'确定删除属性 {name}?',
                                 QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            # 检查是否为元素属性
            if name in self.current_element.attrib:
                # 删除元素属性
                del self.current_element.attrib[name]
            else:
                # 删除Property元素
                for prop in self.current_element.findall('Property'):
                    if prop.get('Name') == name:
                        self.current_element.remove(prop)
                        break
            
            # 删除表格行
            self.property_table.removeRow(current_row)
            
    def update_properties(self):
        """更新属性显示（供外部调用）"""
        self.update_property_table() 